package com.oa.rc.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mdp.core.service.BaseService;
import com.oa.rc.entity.RcSchedule;
import com.oa.rc.entity.RcScheduleExec;
import com.oa.rc.mapper.RcScheduleExecMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * @author maimeng-mdp code-gen
 * @since 2023年10月9日
 */
@Service
public class RcScheduleExecService extends BaseService<RcScheduleExecMapper,RcScheduleExec> {
	static Logger logger =LoggerFactory.getLogger(RcScheduleExecService.class);

	/**
	 * 自定义查询，支持多表关联
	 * @param page 分页条件
	 * @param ew 一定要，并且必须加@Param("ew")注解
	 * @param ext 如果xml中需要根据某些值进行特殊处理，可以通过这个进行传递，非必须，注解也可以不加
	 * @return
	 */
	public List<Map<String,Object>> selectListMapByWhere(IPage page, QueryWrapper ew, Map<String,Object> ext){
		return baseMapper.selectListMapByWhere(page,ew,ext);
	}

	@Autowired
	RcScheduleRecordService rcScheduleRecordService;
	@Autowired
	RcScheduleService rcScheduleService;

	/**
	 * 请在此类添加自定义函数
	 */
	public RcScheduleExec setRcScheduleExec(RcSchedule rcSchedule, String circcleDate) throws UnknownHostException, ParseException {
		RcScheduleExec rcScheduleExec = new RcScheduleExec();
		rcScheduleExec.setId(this.createKey("id"));
		rcScheduleExec.setScheduleId(rcSchedule.getId());
		rcScheduleExec.setExecStatus("0");
		rcScheduleExec.setCtime(new Date());
		rcScheduleExec.setExecDate(circcleDate);
		//获取需要dayofweek
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
		Date dd = sdf2.parse(circcleDate);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dd);

		int weekday = calendar.get(Calendar.DAY_OF_WEEK);
		if("week".equals(rcSchedule.getCircleType())){
			rcScheduleExec.setDayOfWeek(weekday - 1);
		}
		if("month".equals(rcSchedule.getCircleType())){
			rcScheduleExec.setDayOfMonth(calendar.get(Calendar.DATE));
		}
		rcScheduleExec.setExecUserid(rcSchedule.getCreateUserid());
		rcScheduleExec.setExecUsername(rcSchedule.getCreateUsername());
		rcScheduleExec.setExecTitle(rcSchedule.getTitle());
		return rcScheduleExec;
	}

	public void toUpdateDeleteByWhere(RcScheduleExec rcScheduleExec){
		baseMapper.toUpdateDeleteByWhere(rcScheduleExec);
	}

	public String[] setCirccleDates(RcSchedule rcSchedule) throws ParseException {
		String[] circcleDates = new String[0];
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		if ("week".equals(rcSchedule.getCircleType())) {
			circcleDates = rcSchedule.getCircleDaysOfWeek().split(",");
			Date weekDate = new Date();
			Calendar c = Calendar.getInstance();
			c.setTime(weekDate);
//            int monday = c.get(Calendar.MONDAY) + 1;
			Calendar calendar = Calendar.getInstance();
//            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;

			for (int i = 0; i < circcleDates.length; i++) {
				int circcleDate = Integer.parseInt(circcleDates[i]);
				calendar.set(Calendar.DAY_OF_WEEK,circcleDate+1);
				circcleDates[i]=simpleDateFormat.format(calendar.getTime());
				//circcleDates[i] = c.get(Calendar.YEAR) + "-" + monday + "-" + (c.get(Calendar.DATE) + dayOfWeek - circcleDate);
			}
		}
		if ("month".equals(rcSchedule.getCircleType())) {
			circcleDates = rcSchedule.getCircleDaysOfMonth().split(",");
			Date monthDate = new Date();
			Calendar c = Calendar.getInstance();
			c.setTime(monthDate);
			int month=c.get(Calendar.MONTH);
			for (int i = 0; i < circcleDates.length; i++) {
				int circcleDate = Integer.parseInt(circcleDates[i]);
				c.set(Calendar.DAY_OF_MONTH,circcleDate);
				circcleDates[i]=simpleDateFormat.format(c.getTime());
			}
		}
		return circcleDates;
	}

	//定时任务:每天0点进行循环生成日程
	@Scheduled(cron = "0 0/10 0 * * *")
	public void calGradeTime() {
		this.insertNewRcScheduleExec();
	}

	void insertNewRcScheduleExec() {
		Map<String, Object> params = new HashMap<>();
		List<RcSchedule> rcSchedules = rcScheduleService.selectRcShedule(params);
		if (rcSchedules == null || rcSchedules.size() == 0) {
			//do nothing
		} else {

			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
			Calendar calendar1 = Calendar.getInstance();
			Calendar calendar2 = Calendar.getInstance();
			for (RcSchedule rcSchedule : rcSchedules) {
				List<RcScheduleExec> execs = new ArrayList<>();
				calendar1.setTime(rcSchedule.getExecCalcDate());
				calendar2.setTime(rcSchedule.getNextUpdateTime());
				rcSchedule.setExecCalcDate(new Date());
				try {
					if ("week".equals(rcSchedule.getCircleType())) {
						if (calendar1.get(Calendar.WEEK_OF_YEAR) >= calendar2.get(Calendar.WEEK_OF_YEAR)) {
							long time = rcSchedule.getNextUpdateTime().getTime() + 1000 * 60 * 60 * 24 * 7;
							Date nextUpdateTime = new Date(time);
							rcSchedule.setNextUpdateTime(nextUpdateTime);
						}
						if (calendar1.get(Calendar.MONTH) >= calendar2.get(Calendar.MONTH)) {
							String[] circcleDates = this.setCirccleDates(rcSchedule);
							for (String circcleDate : circcleDates) {
								RcScheduleExec rcScheduleExec = this.setRcScheduleExec(rcSchedule, circcleDate);
								execs.add(rcScheduleExec);
							}
						}
					}
					if ("month".equals(rcSchedule.getCircleType())) {
						Calendar c = Calendar.getInstance();
						c.setTime(rcSchedule.getNextUpdateTime());
						int monday = c.get(Calendar.MONDAY) + 2;
						Date nextUpdateTime;
						if (c.get(Calendar.DATE) <= 28) {
							if (monday <= 12) {
								nextUpdateTime = simpleDateFormat.parse((c.get(Calendar.YEAR) + "-" + monday + "-" + c.get(Calendar.DATE)));
							} else {
								nextUpdateTime = simpleDateFormat.parse(((c.get(Calendar.YEAR) + 1) + "-" + 1 + "-" + c.get(Calendar.DATE)));
							}
						} else {
							long ts = rcSchedule.getNextUpdateTime().getTime() + 1000 * 60 * 60 * 24 * 28;
							nextUpdateTime = new Date(ts);
						}
						rcSchedule.setNextUpdateTime(nextUpdateTime);
						if (calendar1.get(Calendar.MONTH) >= calendar2.get(Calendar.MONTH)) {
							String[] circcleDates = this.setCirccleDates(rcSchedule);
							for (String circcleDate : circcleDates) {
								RcScheduleExec rcScheduleExec = this.setRcScheduleExec(rcSchedule, circcleDate);
								execs.add(rcScheduleExec);
							}
						}
					}
				} catch (Exception e) {
					System.out.println(e);
				}
				int i = rcScheduleService.upDateRcSchedule(rcSchedule);
				if (i > 0) {
					this.batchInsert(execs);
				}
			}
		}
	}
}

